package com.ithuameng.admin.app.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ithuameng.admin.app.system.dao.UserMapper;
import com.ithuameng.admin.app.system.model.User;
import com.ithuameng.admin.app.system.model.UserRole;
import com.ithuameng.admin.app.system.model.admin.qo.RoleUserQo;
import com.ithuameng.admin.app.system.model.admin.qo.UserQo;
import com.ithuameng.admin.app.system.service.IUserRoleService;
import com.ithuameng.admin.app.system.service.IUserService;
import com.ithuameng.admin.constants.CommonConstants;
import com.ithuameng.admin.enums.YesNo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * User service implementation
 *
 * @author ithuameng
 */
@Transactional
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private IUserRoleService userRoleService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public IPage<User> listUser(Page<User> page, UserQo userQo) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (userQo != null) {
            if (StringUtils.isNotBlank(userQo.getUsername())) {
                queryWrapper.like(User.USERNAME, userQo.getUsername());
            }
            if (StringUtils.isNotBlank(userQo.getNickname())) {
                queryWrapper.like(User.NICKNAME, userQo.getNickname());
            }
            if (StringUtils.isNotBlank(userQo.getMobile())) {
                queryWrapper.like(User.MOBILE, userQo.getMobile());
            }
            if (userQo.getStatus() != null) {
                queryWrapper.eq(User.STATUS, userQo.getStatus());
            }
        }
        return super.page(page, queryWrapper);
    }

    @Override
    public User getUserByUsername(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(User.USERNAME, username);
        return super.getOne(queryWrapper);
    }

    @Override
    public boolean checkUsernameUnique(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(User.USERNAME, username);
        return super.count(queryWrapper) == 0;
    }

    @Override
    public boolean checkMobileUnique(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return true;
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(User.MOBILE, mobile);
        return super.count(queryWrapper) == 0;
    }

    @Override
    public boolean checkMobileUnique(String mobile, Long execuldeUserId) {
        if (StringUtils.isBlank(mobile)) {
            return true;
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(User.MOBILE, mobile);
        if (execuldeUserId != null) {
            queryWrapper.ne(User.ID, execuldeUserId);
        }
        return super.count(queryWrapper) == 0;
    }

    @Override
    public void saveWithRoles(User user, List<Long> roleIds) {
        super.save(user);
        Long userId = user.getId();
        roleIds.forEach(rid -> {
            UserRole userRole = new UserRole(userId, rid);
            userRoleService.save(userRole);
        });
    }

    @Override
    public void updateWithRoles(User user, List<Long> roleIds) {
        super.updateById(user);
        Long userId = user.getId();
        // 删除旧的
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(UserRole.USER_ID, userId);
        userRoleService.remove(queryWrapper);
        // 保存新的
        roleIds.forEach(rid -> {
            UserRole userRole = new UserRole(userId, rid);
            userRoleService.save(userRole);
        });
        for (int i = 0; i < roleIds.size(); i++) {
            List<Long> userIds = userRoleService.listUserByRoleId(roleIds.get(i));
            userIds.forEach(uid -> {
                String key = CommonConstants.PERMESSION_PREFIX + Long.toString(uid);
                if (stringRedisTemplate.hasKey(key)) {
                    stringRedisTemplate.delete(key);
                }
            });
        }
    }

    @Override
    public void updateStatus(Long userId, YesNo status) {
        User user = new User();
        user.setId(userId);
        user.setStatus(status);
        super.updateById(user);
    }

    @Override
    public void resetPassword(Long userId, String password) {
        User user = new User();
        user.setId(userId);
        user.setPassword(password);
        super.updateById(user);
    }

    @Override
    public void updateUserRole(Long userId, Long[] roleIds) {
        userRoleService.removeByUserId(userId);
        if (roleIds == null) {
            return;
        }
        // 新增用户与角色管理
        List<UserRole> list = new ArrayList<UserRole>();
        for (Long roleId : roleIds) {
            UserRole ur = new UserRole(userId, roleId);
            list.add(ur);
        }
        if (list.size() > 0) {
            userRoleService.saveBatch(list);
        }
    }

    @Override
    public IPage<User> selectAllocatedList(Page<User> page, RoleUserQo roleUserQo) {
        return super.baseMapper.selectAllocatedList(page, roleUserQo.getUsername(), roleUserQo.getMobile(), roleUserQo.getRoleId());
    }

    @Override
    public IPage<User> selectUnallocatedList(Page<User> page, RoleUserQo roleUserQo) {
        return super.baseMapper.selectUnallocatedList(page, roleUserQo.getUsername(), roleUserQo.getMobile(), roleUserQo.getRoleId());
    }

    @Override
    public boolean deleteUserByIds(Long[] userIds) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(User.ID, Arrays.asList(userIds));
        return super.remove(queryWrapper);
    }
}
